from datetime import datetime

import pandas as pd

# 读取文件
file_path = '/data/GuoCu_data/processed_data/click-event_data/all_clicks.csv'
# 添加header=None参数以读取无表头CSV，usecols指定读取前两列
df = pd.read_csv(file_path, usecols=[0, 1])
# 设置列名，第一列label对应'事件'，第二列时间对应'时间'
df.columns = ['label', 'time']
# 将时间列转换为datetime类型
df['time'] = pd.to_datetime(df['time'])

# 分解时间信息
df['day_of_year'] = df['time'].dt.dayofyear
df['month'] = df['time'].dt.month
# 将weekday重命名为day_of_week以符合命名规范
df['day_of_week'] = df['time'].dt.dayofweek
# 添加day_of_month字段（月份中的第几天）
df['day_of_month'] = df['time'].dt.day
df['is_weekend'] = df['day_of_week'].apply(lambda x: 1 if x >= 5 else 0)

# 这里仅简单标记，实际节假日需要更复杂的判断逻辑，可根据实际情况替换
# 假设没有额外的节假日数据，仅保留周末判断
# df['是否是节假日'] = ...

# 读取文件，添加第九列(索引8)和第十至二十七列(索引9-26)
file_path = '/data/GuoCu_data/processed_data/click-event_data/all_clicks.csv'
# 合并需要读取的列索引：前6列 + 第9列 + 10-27列
columns_to_read = list(range(0,6)) + [8] + list(range(9,29))
df = pd.read_csv(file_path, usecols=columns_to_read)
# 设置列名，包含新增的user_user_last_login_time和原始10-27列(临时命名为col_9至col_26)
df.columns = ['label', 'time', 'id', 'ip', 'userId', 'contentId', 
'user_user_last_login_time','user_user_login_count_7d', 'user_user_is_login_3d', 
'user_user_total_clicks', 'user_user_click_ts_diff_min', 'user_user_click_ts_diff_mean',
'user_user_click_ts_diff_std', 'user_user_click_ts_diff_max', 'user_user_click_ts_hour_mean', 
'user_last_click_time', 'item_category_rank', 'item_position_rank', 'item_click_total',
'item_item_click_num_3d', 'item_item_click_num_7d', 
'item_item_click_num_14d', 'item_item_click_num_21d', 'item_item_click_rank_3d', 
'item_item_click_rank_7d', 'item_item_click_rank_14d', 'item_item_click_rank_21d']

# 分解IP地址为四个部分
# 先处理可能的缺失值或非标准IP格式
df['ip'] = df['ip'].fillna('0.0.0.0')
# 分割IP地址为四列
df[['ip-1', 'ip-2', 'ip-3', 'ip-4']] = df['ip'].str.split('.', expand=True)
# 转换为整数类型
df[['ip-1', 'ip-2', 'ip-3', 'ip-4']] = df[['ip-1', 'ip-2', 'ip-3', 'ip-4']].astype(int)

# 将时间列转换为datetime类型
df['time'] = pd.to_datetime(df['time'], errors='coerce')

# 新增：处理user_user_last_login_time列
# 处理登录时间列（指定ISO 8601格式）
df['user_user_last_login_time'] = pd.to_datetime(df['user_user_last_login_time'], format='%Y-%m-%dT%H:%M:%S', errors='coerce')
# 分裂登录时间特征
df['last_login_day_of_year'] = df['user_user_last_login_time'].dt.dayofyear
df['last_login_month'] = df['user_user_last_login_time'].dt.month
df['last_login_day_of_week'] = df['user_user_last_login_time'].dt.dayofweek
df['last_login_day_of_month'] = df['user_user_last_login_time'].dt.day
df['last_login_is_weekend'] = df['last_login_day_of_week'].apply(lambda x: 1 if x >= 5 else 0)
# 删除原始登录时间列
df.drop('user_user_last_login_time', axis=1, inplace=True)

# 分解时间信息
df['day_of_year'] = df['time'].dt.dayofyear
df['month'] = df['time'].dt.month
# 将weekday重命名为day_of_week以符合命名规范
df['day_of_week'] = df['time'].dt.dayofweek
# 添加day_of_month字段（月份中的第几天）
df['day_of_month'] = df['time'].dt.day
df['is_weekend'] = df['day_of_week'].apply(lambda x: 1 if x >= 5 else 0)

# 这里仅简单标记，实际节假日需要更复杂的判断逻辑，可根据实际情况替换
# 假设没有额外的节假日数据，仅保留周末判断
# df['是否是节假日'] = ...

# 这里仿照time的处理方式对user_last_click_time进行处理
df['user_last_click_time'] = pd.to_datetime(df['user_last_click_time'], format='%Y-%m-%dT%H:%M:%S', errors='coerce')
# 分裂登录时间特征
df['last_click_day_of_year'] = df['user_last_click_time'].dt.dayofyear
df['last_click_month'] = df['user_last_click_time'].dt.month
df['last_click_day_of_week'] = df['user_last_click_time'].dt.dayofweek
df['last_click_day_of_month'] = df['user_last_click_time'].dt.day
df['last_click_is_weekend'] = df['last_click_day_of_week'].apply(lambda x: 1 if x >= 5 else 0)
# 删除原始登录时间列
df.drop('user_last_click_time', axis=1, inplace=True)

# # 添加哈希分桶处理
# # 设置分桶数量，可根据需要调整
# num_buckets = 30
# # 使用独立哈希函数对id进行分桶
# df['id-hash_bucket'] = df['id'].apply(lambda x: hash(str(x)) % num_buckets)
# # 删除原始id列，仅保留分桶结果
# df.drop('id', axis=1, inplace=True)

# # 添加userId哈希分桶处理
# df['user_id_hash_bucket'] = df['userId'].apply(lambda x: hash(str(x)) % num_buckets)
# # 删除原始userId列
# df.drop('userId', axis=1, inplace=True)

# 方法1: 使用pandas的factorize
df['id_encoded'], _ = df['id'].factorize()
df.drop('id', axis=1, inplace=True)

# 方法2: 使用sklearn的LabelEncoder
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
df['user_id_encoded'] = le.fit_transform(df['userId'])
df.drop('userId', axis=1, inplace=True)


# 处理contentId映射为0-29的数字
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
# 使用LabelEncoder将contentId转换为0开始的整数
df['content_id_encoded'] = le.fit_transform(df['contentId'])
# 确保编码值在0-29范围内
max_encoded_value = df['content_id_encoded'].max()
if max_encoded_value > 29:
    # 如果唯一值超过30个，使用哈希分桶确保在0-29范围内
    df['content_id_encoded'] = df['contentId'].apply(lambda x: hash(str(x)) % 30)
df.drop('contentId', axis=1, inplace=True)



# 调整列顺序，按逻辑顺序排列特征并保留原始10-27列
columns = ['label', 'month', 'day_of_month', 'day_of_week', 'day_of_year', 
'is_weekend', 'id_encoded', 'user_id_encoded', 'content_id_encoded', 
'last_login_day_of_year', 'last_login_month', 'last_login_day_of_week', 
'last_login_day_of_month', 'last_login_is_weekend', 'ip-1', 'ip-2', 'ip-3', 'ip-4',
'user_user_login_count_7d', 'user_user_is_login_3d', 'user_user_total_clicks', 
'user_user_click_ts_diff_min', 'user_user_click_ts_diff_mean', 'user_user_click_ts_diff_std', 
'user_user_click_ts_diff_max', 'user_user_click_ts_hour_mean', 'last_click_day_of_year', 'last_click_month', 'last_click_day_of_week', 
'last_click_day_of_month', 'last_click_is_weekend', 'item_category_rank', 
'item_position_rank', 'item_click_total',
'item_item_click_num_3d', 'item_item_click_num_7d', 
'item_item_click_num_14d', 'item_item_click_num_21d', 'item_item_click_rank_3d', 
'item_item_click_rank_7d', 'item_item_click_rank_14d', 'item_item_click_rank_21d']
df = df[columns]
# 保存到新文件（不同于之前的输出路径）
output_path = '/data/GuoCu_data/processed_data/toGBDT.csv'
df.to_csv(output_path, index=False)
